package colibri.lcdui;

import colibri.App;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**Cria uma Scroll Bar.
 * 
 * @author Bayron Thiengo Quinelato
 */
class ScrollBar extends Item {

    private static Image imArrowUp;
    private static Image imArrowDown;
    private static Image imBackground;
    private static Image imBarBorderUp;
    private static Image imBarBorderDown;
    private static Image imBar;
    private static boolean refreshDimension = false;
    private static int colorBackground = 0x00EFEFEF;
    private static int colorBar = 0x00BBBBBB;
    private static int colorBarBorder = 0x00979797;
    private int formH;
    private int offset;
    private int barOffset;
    private int barY;
    private int barH, arrowsH;
    private int count, maxCount;
    private boolean active;

    public ScrollBar(Form form, int y, int height) {
        super(App.width, y, 0, height, Graphics.TOP | Graphics.RIGHT);
        if (form == null)
            return;
        setCanvas(form);
        focusable = false;
        active = false;
        setDimensions();
    }

    private void setDimensions() {
        try {
            if (getCanvas() == null)
                return;
            Form form = (Form) getCanvas();
            this.formH = form.getFormHeight() - getY();
            if (imBackground == null)
                setWidth(8);
            else
                setWidth(imBackground.getWidth());

            if (imArrowUp == null || imArrowDown == null)
                arrowsH = 0;
            else
                if (imArrowUp.getHeight() > imArrowDown.getHeight())
                    arrowsH = imArrowUp.getHeight();
                else
                    arrowsH = imArrowDown.getHeight();
            barH = ((getHeight() - 2 * arrowsH) * getHeight()) / formH;

            offset = (int) (0.15 * getHeight());
            barOffset = (offset * (getHeight() - 2 * arrowsH)) / formH;

            count = 0;
            maxCount = (formH - getHeight()) / offset;
            if ((formH - getHeight()) % offset > 0) {
                maxCount++;
            }
            refreshDimension = false;
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public void up() {
        if (visible && active && count > 0)
            count--;
    }

    public void down() {
        if (visible && active && count < maxCount)
            count++;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getCount() {
        return count;
    }

    public int getMaxCount() {
        return maxCount;
    }

    public final int getOffset() {
        return offset;
    }

    public static void setImages(Image imBackground, Image imArrowUp, Image imArrowDown, Image imBar, Image imBarBorderUp, Image imBarBorderDown) {
        if (imBackground == null || imArrowUp == null || imArrowDown == null || imBar == null || imBarBorderUp == null || imBarBorderDown == null)
            return;
        ScrollBar.imBackground = imBackground;
        ScrollBar.imArrowUp = imArrowUp;
        ScrollBar.imArrowDown = imArrowDown;
        ScrollBar.imBackground = imBackground;
        ScrollBar.imBar = imBar;
        ScrollBar.imBarBorderUp = imBarBorderUp;
        ScrollBar.imBarBorderDown = imBarBorderDown;
        refreshDimension = true;
    }

    public static void setColors(int colorBackground, int colorBar, int colorBarBorder) {
        ScrollBar.colorBackground = colorBackground;
        ScrollBar.colorBar = colorBar;
        ScrollBar.colorBarBorder = colorBarBorder;
    }

    protected final void callPaint(Graphics g) {
        if (refreshDimension)
            setDimensions();
        if (imBackground == null || imArrowUp == null || imArrowDown == null || imBar == null || imBarBorderUp == null || imBarBorderDown == null) {
            // Desenha o fundo
            g.setColor(colorBackground);
            g.fillRect(getX() - getWidth(), getY(), getWidth(), getHeight());
            // Desenha a barra que se move
            if (barH > 0) {
                if (count < maxCount)
                    barY = getY() + arrowsH + count * barOffset;
                else
                    barY = getY() + getHeight() - arrowsH - barH;
                g.setColor(colorBarBorder);
                g.drawRect(getX() - getWidth(), barY, getWidth() - 1, barH - 1);
                g.setColor(colorBar);
                g.fillRect(getX() - getWidth() + 1, barY + 1, getWidth() - 2, barH - 2);
            }
        } else {
            // Desenha o fundo
            if (imBackground.getHeight() < getHeight() - 2 * arrowsH)
                for (int i = getY() + arrowsH; i < getY() + getHeight() - arrowsH; i += imBackground.getHeight())
                    g.drawImage(imBackground, getX(), i, anchor);
            else
                g.drawImage(imBackground, getX(), getY(), anchor);
            // Desenha as setas
            g.drawImage(imArrowUp, getX(), getY(), anchor);
            g.drawImage(imArrowDown, getX(), getY() + getHeight() - imArrowDown.getHeight(), anchor);
            // Desenha a barra que se move
            if (barH > 0) {
                if (count < maxCount)
                    barY = getY() + arrowsH + count * barOffset;
                else
                    barY = getY() + getHeight() - arrowsH - barH;

                if (imBar.getHeight() < barH)
                    for (int i = barY + imBarBorderUp.getHeight(); i < barY + barH - imBarBorderDown.getHeight(); i += imBar.getHeight())
                        g.drawImage(imBar, getX(), i, anchor);
                else
                    g.drawImage(imBar, getX(), barY, anchor);
                g.drawImage(imBarBorderUp, getX(), barY, anchor);
                g.drawImage(imBarBorderDown, getX(), barY + barH - imBarBorderDown.getHeight(), anchor);
            }
        }
    }

    protected final void callKeyReleased(int keyCode) {
        int gameAction = App.getGameAction(keyCode);
        switch (gameAction) {
            case App.UP:
                //up();
                break;
            case App.DOWN:
                //down();
                break;
        }
    }

    protected final void callKeyRepeated(int keyCode) {
        callKeyReleased(keyCode);
    }

    protected final void callPointerReleased(int x, int y) {
        if (x > getX() - getWidth()) {
            if (count == 0) {
                if (y > getY() + barH) {
                    down();
                }
            } else if (count == maxCount) {
                if (y < getY() + barY) {
                    up();
                }
            } else {
                if (y > getY() && y < getY() + barY) {
                    up();
                } else if (y >= getY() + barY + barH && y < getY() + getHeight()) {
                    down();
                }
            }
        }
    }

    protected final void callPointerDragged(int x, int y) {
        callPointerReleased(x, y);
    }
}
